

enum HTTPMethod: String {
    case GET
    case POST
    case PUT
    case DELETE
}


struct APIResponse<T: Decodable>: Decodable {
    let code: Any  // 使用 `Any` 来处理 String 或 Int 的情况, 没办法：蜜飞code是string，凯度code是int，哎！
    let msg: String?
    let data: T?

    enum CodingKeys: String, CodingKey {
        case code
        case msg
        case data
    }

    // 自定义解码 `code` 字段
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 处理 `code` 字段，可能是 `String` 或 `Int`
        if let intCode = try? container.decode(Int.self, forKey: .code) {
            self.code = intCode
        } else if let stringCode = try? container.decode(String.self, forKey: .code) {
            self.code = stringCode
        } else {
            self.code = "Unknown"  // 默认值
        }
        
        // 解码其他字段
        self.msg = try container.decodeIfPresent(String.self, forKey: .msg)
        self.data = try container.decodeIfPresent(T.self, forKey: .data)
    }
}

struct EmptyBody: Encodable, Equatable {}
struct EmptyResponseData: Encodable, Equatable {}

protocol API {
    associatedtype RequestBody: Encodable = EmptyBody
    associatedtype Response: Decodable = EmptyResponseData

    var path: String { get }
    var method: HTTPMethod { get }
    var headers: [String: String] { get }
    var body: RequestBody? { get }
    var query: [String: String]? { get }
    var pathValues: [String: String]? { get }
    var requiresEncryption: Bool { get }
    func withUpdatedHeaders(_ headers: [String: String]) -> Self
}

extension API{
    var requiresEncryption: Bool {
        return false
    }
    
    var headers:[String: String] {
        return ["Content-Type": "application/json"]
    }
}


extension API {
    func updatedHeaders(_ newHeaders: [String: String]) -> Self {
        var updatedAPI = self
        var updatedHeaders = newHeaders
        updatedHeaders.merge(self.headers) { current, _ in current }
        updatedAPI = updatedAPI.withUpdatedHeaders(updatedHeaders)
        return updatedAPI
    }
}
